package net.wicp.tams.common.apiext;

import java.io.InputStreamReader;
import java.io.Reader;

import io.thekraken.grok.api.Grok;
import io.thekraken.grok.api.Match;
import io.thekraken.grok.api.exception.GrokException;
import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Result;

/**
 * 
 * @author 偏锋书生
 *
 */
@Slf4j
public class GrokObj {
	private static volatile GrokObj INSTANCE;
	private final Grok defaultGrok;

	private GrokObj() {
		defaultGrok = new Grok();
		Reader reader = new InputStreamReader(IOUtil.fileToInputStream("/patterns/grok-patterns", GrokObj.class));
		try {
			defaultGrok.addPatternFromReader(reader);
		} catch (GrokException e) {
			log.error("读配置文件错误，默认的Grok创建失败",e);
		}
	}

	public static final GrokObj getInstance() {
		if (INSTANCE == null) {
			synchronized (GrokObj.class) {
				if (INSTANCE == null) {
					INSTANCE = new GrokObj();
				}
			}
		}
		return INSTANCE;
	}

	public Result addPattern(String name, String pattern) {
		if (StringUtil.isNull(name) || StringUtil.isNull(pattern)) {
			return Result.getError("缺少参数");
		}
		try {
			defaultGrok.addPattern(name, pattern);
			return Result.getSuc();
		} catch (GrokException e) {
			log.error("加规则失败", e);
			return Result.getError("加规则失败");
		}
	}

	public <T> Result addPatternFile(String path, Class<T> classz) {
		try {
			Reader reader = new InputStreamReader(IOUtil.fileToInputStream(path, classz));
			defaultGrok.addPatternFromReader(reader);
			return Result.getSuc();
		} catch (GrokException e) {
			log.error("加规则文件失败", e);
			return Result.getError("加规则文件失败");
		}
	}

	public <T> Result addPatternFile(String path) {
		return addPatternFile(path, null);
	}

	public Result addPatternFile(PatternType path) {
		if (path == null) {
			return Result.getError("加规则文件失败");
		}
		return addPatternFile(String.format("/patterns/%s", path.getPath()), GrokObj.class);
	}

	public Grok getDefaultGrok() {
		return defaultGrok;
	}

	public Match match(String pattern, String text) throws GrokException {
		defaultGrok.compile(pattern);
		Match gm = defaultGrok.match(text);
		gm.captures();
		return gm;
	}

	public static enum PatternType {
		firewalls("firewalls"), grokPatterns("grok-patterns"), haproxy("haproxy"), java("java"), junos(
				"junos"), linuxSyslog("linux-syslog"), mcollective("mcollective"), mcollectivePatterns(
						"mcollective-patterns"), mongodb("mongodb"), nagios("nagios"), postgresql("postgresql"), redis(
								"redis"), ruby("ruby");

		private final String path;

		public String getPath() {
			return path;
		}

		private PatternType(String path) {
			this.path = path;
		}
	}
}
